﻿using NHibernate;
using SmartRS.com.vn.smartrs.domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmartRS.com.vn.smartrs.interfaces;

namespace SmartRS.com.vn.smartrs.dao
{
    public class BaseDao<T> : BaseDbInterface<T> where T : BaseDomain
    {

        public T insert(T obj)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        obj.deteleFlag = false;
                        session.Save(obj);
                        session.Flush();
                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        if (transaction.WasCommitted)
                        {
                            transaction.Rollback();
                            //When insert fail
                            return null;
                        }
                        throw new Exception("Insert happened error: " + ex.Message);
                    }
                }
            }
            return obj;

        }

        public bool update(T obj)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.Update(obj);
                        transaction.Commit();
                        return true;
                    }
                    catch (Exception ex)
                    {
                        if (transaction.WasCommitted)
                        {
                            transaction.Rollback();
                            Console.WriteLine("Delete commited error: " + ex.Message);
                            return false;
                        }
                        throw new Exception("Update happened error: " + ex.Message);
                    }
                }
            }
        }

        public bool delete(T obj)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        obj.deteleFlag = true;
                        session.Update(obj);
                        transaction.Commit();
                        return true;
                    }
                    catch (Exception ex)
                    {
                        if (transaction.WasCommitted)
                        {
                            transaction.Rollback();
                            Console.WriteLine("Delete commited error: " + ex.Message);
                            return false;
                        }
                        throw new Exception("Delete happened error: " + ex.Message);
                    }

                }
            }
        }

        public T getById(long id)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                try
                {
                    var obj = session.Get<T>(id);
                    if (obj.deteleFlag)
                    {
                        return null;
                    }
                    return obj;
                }
                catch(Exception ex)
                {
                    throw new Exception("Get data by id happened error: " + ex.Message);
                }
            }
        }

        public IList<T> getAll()
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                try
                {
                    //return (from e in session.QueryOver<T>() select e).List();
                    return session.CreateCriteria<T>().List<T>().Where(x => x.deteleFlag == false).ToList<T>();
                }
                catch (Exception ex)
                {
                    throw new Exception("Get list data happened error: " + ex.Message);
                }
            }
        }
    }
}
